<template>
  <div
    class="w-full h-full cursor-grab overflow-hidden inline-block relative"
    ref="wrapper"
  >
    <div class="content w-full">
      <div
        v-if="pullDown"
        class="w-full h-full flex justify-center items-center"
      >
        <img class="text-[#f00]" src="@/assets/images/tail-spin.svg" alt="" />
      </div>
      <div
        v-if="messageMore"
        class="w-full h-full flex justify-center items-center text-[15px]"
      >
        暂无更多消息
      </div>
      <slot></slot>
    </div>
  </div>
</template>
<script setup lang="ts">
  import { useSize } from '@/hooks/useSize'
  import emitter from '@/plugins/mitt'
  import { loadHistoryMessage } from '@/plugins/session'
  import { useSessionStore } from '@/store/session'
  import BScroll, {
    MouseWheel,
    ObserveDom,
    ObserveImage,
    PullDownRefresh,
    ScrollBar,
  } from 'better-scroll'
  import { onMounted, onUnmounted, ref, watch } from 'vue'
  const pullDown = ref(false)
  const messageMore = ref(false)
  BScroll.use(MouseWheel)
  BScroll.use(PullDownRefresh)
  BScroll.use(ObserveDom)
  BScroll.use(ObserveImage)
  BScroll.use(ScrollBar)
  const wrapper = ref()
  const { height } = useSize(wrapper)
  const bs = ref()

  onMounted(() => {
    bs.value = new BScroll(wrapper.value, {
      probeType: 2,
      scrollY: true,
      mouseWheel: true,
      observeDOM: true,
      observeImage: true,
      click: true,
      bindToWrapper: true,
      pullDownRefresh: {
        threshold: 90,
        stop: 40,
      },
      resizePolling: 200,
      scrollbar: false,
    })
    bs.value.on('pullingDown', handleWatchPullingDown)
    bs.value.scroller.hooks.on('resize', () => {
      console.log("window's size has changed")
      refreshScroll()
    })
  })

  watch(
    () => height.value,
    () => {
      refreshScroll()
      scrollBottom()
    },
    {
      immediate: false,
      deep: true,
    },
  )
  // 监听下拉刷新
  const handleWatchPullingDown = async () => {
    const session = useSessionStore()
    if (session.historyPaging.more) {
      if (messageMore.value) {
        bs.value.finishPullDown()
        return false
      }
      pullDown.value = true
      loadHistoryMessage().then((result: any) => {
        if (result.messages.length === 0) {
          pullDown.value = false
          messageMore.value = true
          bs.value.finishPullDown()
        } else {
          pullDown.value = false
          bs.value.finishPullDown()
        }
      })
    } else {
      messageMore.value = true
      bs.value.finishPullDown()
      return false
    }
  }
  // 重置滚动区域并重新计算高度
  const refreshScroll = async () => {
    bs && bs.value.refresh()
  }
  emitter.on('scrollBottom', () => {
    scrollBottom()
  })
  const scrollBottom = () => {
    setTimeout(() => {
      bs && bs.value.scrollTo(0, bs.value.maxScrollY, 500)
    }, 300)
  }
  const scrollTop = () => {
    bs && bs.value.scrollTo(0, bs.value.minScrollY, 500)
  }
  onUnmounted(() => {
    bs.value.destroy()
    emitter.off('scrollBottom')
  })
  defineExpose({
    refreshScroll,
    scrollBottom,
    scrollTop,
    handleWatchPullingDown,
  })
</script>

<style scoped></style>
